import { getCanvas, getCanvasImage, getImageInstance } from '@/components/OffScreenCanvas/data'
import { server } from '../config'
import { canUseWebpFormat, supportWebp } from './check'

/**
 * 合成图片路径
 * @param relativePath 图片相对路径
 * @returns 图片路径
 */
const imagePathOnly = (relativePath: string, webp = true) => {
  const type = getImageType(relativePath)

  return `${server.srcServer}images/${
    webp && supportWebp && canUseWebpFormat[type]
      ? `${relativePath.slice(0, -type.length)}webp`
      : relativePath
  }`
}

/**
 * 合成样式图片路径
 * @param relativePath 图片相对路径
 * @returns 图片路径
 */
const imagePath = (relativePath: string, webp = true) => `url(${imagePathOnly(relativePath, webp)})`

/**
 * Mask样式
 * @param path 图片路径
 * @returns 样式
 */
const maskStyle = (path: string) => ({
  maskImage: path,
  '-webkit-mask-image': path,
  '-webkit-mask-box-image': path,
})

export { imagePathOnly, imagePath, maskStyle }

type T_ImageInfo = {
  src: string
  size: number
  width: number
  height: number
  type: string
  ins?: any // 兼容APP
}

// 图片类型白名单
const imageTypeWhite = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'heif', 'heic']

/**
 * 选择图片
 * @param count 选择数量
 * @param cb 成功回调
 */
const chooseImages = (count = 1, cb = (_res: UniApp.ChooseImageSuccessCallbackResult) => {}) => {
  uni.chooseImage({
    // APP
    count,
    // WEB || MP
    extension: imageTypeWhite,
    // WEB || MP
    sizeType: ['compressed'], //可以指定是原图还是压缩图，默认二者都有
    success: res => cb(res),
  })
}

/**
 * 获取图片类型
 * @param path 图片路径
 */
const getImageType = (path: string) => {
  if (path.startsWith('image/')) return path.split('image/')[1]

  path = path.split('/').pop() || ''

  const words = path.split('.')

  return words.length > 1 ? words[words.length - 1].toLowerCase() : ''
}

/**
 * 读取图片信息
 * @param file 图片文件, 不同平台格式如下
 *  // WEB
    {
      path: "blob:http://localhost:5173/55bcd216-8d54-4e20-8eb7-46e3c2e135ba"
      lastModified: 1744967856314
      lastModifiedDate: Fri Apr 18 2025 17:17:36 GMT+0800 (中国标准时间) {}
      name: "20250418-171738.png"
      size: 2508446
      type: "image/png"
      webkitRelativePath: ""
    }
 *
 *  // MP
    {
      "path": "http://tmp/XbREFdmSPSiT35cb83e1c4c676e4de218e46fa1ca6e1.png",
      "size": 2233453
    }
 *
 *  // APP
    {
      "path": "file:///storage/emulated/0/DCIM/tieba/E045F91DED4C1FC1509F2C410C1ECFB4.jpg",
      "size": 674126
    }
 */
const readImage = async (file: any): Promise<T_ImageInfo> => {
  const res = await new Promise<UniApp.GetImageInfoSuccessData>((resolve, reject) => {
    uni.getImageInfo({
      src: file.path,
      success: resolve,
      fail: reject,
    })
  })

  return {
    src: res.path,
    size: file.size,
    width: res.width,
    height: res.height,
    type: getImageType(file.type || file.name || file.path),
    // #ifdef WEB || MP
    ins: await getImageInstance(res.path),
    // #endif
  }
}

/** 最大长短边比值 */
const aspectMax = 2000 / 768

/**
 * 标准化图片
 * @param data 图片数据
 */
const normalizeImage = async (info: T_ImageInfo) => {
  const imageType = info.type || 'jpg'

  if (!~imageTypeWhite.indexOf(imageType)) throw '不支持的图片类型'

  // if (info.width < 768 || info.height < 768) {
  //   throw '图片尺寸过小 ' + info.width + ' ' + info.height
  // }

  // 计算长短边缩放比
  const isHorizontal = info.width > info.height
  let longSide = 0
  let shortSide = 0

  if (isHorizontal) {
    longSide = info.width
    shortSide = info.height
  } else {
    longSide = info.height
    shortSide = info.width
  }

  const aspect = longSide / shortSide

  if (aspect > aspectMax) throw '图片长短边比例不能超过 2.6 : 1'

  let dpr = 1
  // #ifdef APP
  dpr = uni.getWindowInfo().pixelRatio
  // #endif

  const ratio = (shortSide / 768) * dpr
  const long = Math.round(longSide / ratio)
  const short = Math.round(shortSide / ratio)
  const width = Math.round(isHorizontal ? long : short)
  const height = Math.round(isHorizontal ? short : long)

  // canvas重绘
  const { ctx } = await getCanvas(width, height)

  ctx.drawImage(info.ins || info.src, 0, 0, info.width, info.height, 0, 0, width, height)

  // #ifdef APP
  await new Promise(resolve => ctx.draw(true, resolve))
  // #endif

  // 导出画面
  const src = await getCanvasImage()

  return { src, width, height }
}

/**
 * 下载图片
 * @param src 网络路径
 */
const downloadImage = async (src: string) => {
  const res = await new Promise<UniApp.GetImageInfoSuccessData>((resolve, reject) => {
    uni.getImageInfo({
      src,
      success: resolve,
      fail: reject,
    })
  })

  await new Promise((resolve, reject) =>
    uni.saveImageToPhotosAlbum({
      filePath: res.path,
      success: resolve,
      fail: reject,
    }),
  )
}

export { chooseImages, readImage, normalizeImage, downloadImage }
